package dataspace

type fraction struct {
	m byte   // mode/режим
	s bool   // status/статус
	k []byte // key/ключ
	v []byte // value/значение
}

/*
Функция сериализует блок данных в бинарный код. Блок состоит из метаданных размером 8 байт
и основой фракции пространство-ключ-значение.

Метаданные:

		         +------------+------------+------------+------------+
	::: name ::: | mode       | status     | key size   | value size |
		         +------------+------------+------------+------------+
	::: size ::: | 1          | 1          | 2          | 4          |
		         +------------+------------+------------+------------+
*/
func encode(f *fraction) []byte {
	b := make([]byte, 0, len(f.k)+len(f.v))
	b = writeByte(b, f.m)
	b = writeBool(b, f.s)
	b = writeUint16(b, uint16(len(f.k)))
	b = writeUint32(b, uint32(len(f.v)))
	b = append(b, f.k...)
	b = append(b, f.v...)
	return b
}

// Функция разбивает общий срез данных на блоки.
func decode(data []byte) []*fraction {
	i, fractions := 0, make([]*fraction, 0)
	for i < len(data) {
		klen := getUint16(data[i+2 : i+4])
		vlen := getUint32(data[i+4 : i+8])
		fractions = append(fractions, &fraction{
			m: data[i],
			s: getBool(data[i+1]),
			k: data[i+8 : i+8+int(klen)],
			v: data[i+8+int(klen) : i+8+int(klen)+int(vlen)],
		})
		i += 8 + int(klen) + int(vlen)
	}
	return fractions
}
